package com.decoration.basic.interceptor;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.decoration.basic.entity.JsonResult;
import com.decoration.basic.filter.HttpServletRequestFilter;
import com.decoration.basic.util.Global;
import com.decoration.basic.util.HttpContextUtils;
import com.decoration.basic.util.SessionSingleton;
import com.decoration.basic.util.StringUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Component
public class ApiInterceptor implements HandlerInterceptor {
	private static final Logger log = LoggerFactory.getLogger(ApiInterceptor.class);
//默认放行地址
	private static final List<String> permitList = Arrays.asList("/api/user/login",
			"/admin/user/login","/api/caselist","/api/casebyid",
			"/api/user/designer/list");
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception {

		//响应信息配置
		response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Accept, Content-Type,Authorization");
		response.setHeader("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
		response.setHeader("Access-Control-Allow-Origin", "*");
		//log.info("请求网址:["+request.getServerName());
		if (request instanceof HttpServletRequestFilter.RequestWrapper){
			HttpServletRequestFilter.RequestWrapper requestWrapper = (HttpServletRequestFilter.RequestWrapper)request;
			String nowParam = HttpContextUtils.getBodyString(requestWrapper);
			if (StringUtil.isEmpty(nowParam)){
				log.info("获取paramterMap参数");
				nowParam = JSONUtil.toJsonStr(request.getParameterMap());
			}
			log.info("requestBody:["+nowParam+"]");
		}

		log.info("请求网址:["+getIpAdrress(request)+"]");
		if ("localhost".equals(request.getServerName())) {
			log.info("本地请求不做校验:" + JSON.toJSONString(request.getRequestedSessionId()));
			log.info("preHandle-getRequestURI:" + request.getRequestURI());
			return true;
		}
		log.info("交易编码:" + request.getRequestURI());
		// 登陆路径放行
		if (permitList.contains(request.getRequestURI())) {
			log.info("默认放行地址");
			return true;
		}

		// 权限路径拦截
		// 无论访问的地址是不是正确的，都进行登录验证，登录成功后的访问再进行分发，404的访问自然会进入到错误控制器中
		HttpSession session = request.getSession();
		if (session != null) {
			Object object = session.getAttribute(Global.SESSION_USER_ID);
			if (object != null && !"".equals(object.toString())) {
//				try {
				// 验证当前请求的session是否是已登录的session
//	            String loginSessionId = redisTemplate.opsForValue().get(Constans.AUTO_USER_TOKEN + session.getAttribute(Constans.USER_SESSION_ID));

				log.info("session object:" + object);
				String loginSessionId = null;
				HttpSession LoginSession = null;
				//小程序登录
				if (request.getRequestURI().indexOf("/api", 0) >= 0) {
					LoginSession = SessionSingleton.getInstance().getClientSession(object.toString());
					if (LoginSession == null) {
						resFail(response, JsonResult.FAILED_UNLGIN, "用户未登录或已过期！");
						return false;
					}
					loginSessionId = LoginSession.getId();
					if (loginSessionId != null && loginSessionId.equals(session.getId())) {
						//登录态不为空
//		                	String redisTimeOut = sysconfigService.getSysconfig(Constans.TOKEN_TIME_OUT);
//		                    if (StringUtil.isEmpty(redisTimeOut)) {
//		                    	redisTimeOut = "30";
//		            		}
//		                    Long timeOut = Long.parseLong(redisTimeOut) * 60;
//		                	redisTemplate.opsForValue().set(Constans.AUTO_USER_TOKEN +
// 								session.getAttribute(Constans.USER_SESSION_ID), loginSessionId, timeOut, TimeUnit.SECONDS);
					}
				}
				//后端登录
				else if (request.getRequestURI().indexOf("/admin", 0) >= 0) {
					LoginSession = SessionSingleton.getInstance().getServiceSession(object.toString());
					if (LoginSession == null) {
						resFail(response, JsonResult.FAILED_UNLGIN, "用户未登录或已过期！");
						return false;
					}
					loginSessionId = LoginSession.getId();
					if (loginSessionId != null && loginSessionId.equals(session.getId())) {
						//登录态控制
//		                	String redisTimeOut = sysconfigService.getSysconfig(Constans.TOKEN_TIME_OUT);
//		                    if (StringUtil.isEmpty(redisTimeOut)) {
//		                    	redisTimeOut = "30";
//		            		}
//		                    Long timeOut = Long.parseLong(redisTimeOut) * 60;
//		                	redisTemplate.opsForValue().set(Constans.AUTO_USER_TOKEN + session.getAttribute(Constans.USER_SESSION_ID), loginSessionId, timeOut, TimeUnit.SECONDS);
//                		// 根据用户类型，判断是否由请求接口的权限
						Integer perType = (Integer) request.getSession().getAttribute(Global.SESSION_USER_TYPE);
						if (!perType.equals(Global.USER_MANAGER)) {
							resFail(response, JsonResult.FAILED_UNPERMISSION, "用户没有权限！");
							return false;
						}
					}
				}
				//通用组件放行
				else if (request.getRequestURI().indexOf("/common", 0) == 0) {
					return true;
				}
				//其他路径组件功能
				else {
					resFail(response, JsonResult.FAILED_ACCOUNT_ABNORMAL, "未知交易类型，拒绝访问！");
					return false;
				}

				//校验登录状态  会话id不为空且不等于此会话id  校验会话sessionid--
				if (loginSessionId != null && !loginSessionId.equals(session.getId())) {
					resFail(response, JsonResult.FAILED_OTHER_LGIN, "当前账号已在别处被登录" + loginSessionId);
					return false;
				}
				//会话id为空 或者为''
				if (loginSessionId == null || StringUtils.isEmpty(loginSessionId)) {
					resFail(response, JsonResult.FAILED_ACCOUNT_ABNORMAL, "无登录信息,请重新登录");
					return false;
				}
			} else {
				resFail(response, JsonResult.FAILED_UNLGIN, "用户未登录或已过期！");
				return false;
			}
		} else {
			resFail(response, JsonResult.FAILED_UNLGIN, "请求数据错误，Session为空！");
			return false;
		}
		return true;
	}

	private void resFail(HttpServletResponse response, int code, String msg) {
		response.reset();
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json; charset=utf-8");

		try {
			JsonResult jsonResult = new JsonResult();
			jsonResult.setMsg(msg);
			jsonResult.setCode(code);
			jsonResult.setData(new ArrayList<>());
			response.getWriter().print(JSON.toJSONString(jsonResult));
			response.getWriter().close();
		} catch (IOException e) {
			log.error("响应报文写入异常！",e );
		}
	}

	@Override
	public void postHandle(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o,
						   ModelAndView modelAndView) throws Exception {

	}

	@Override
	public void afterCompletion(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse,
								Object o, Exception e) throws Exception {
//		log.info("响应信息:" + JSONUtil.toJsonStr(o));
	}

	private static String getIpAdrress(HttpServletRequest request) {
		String Xip = request.getHeader("X-Real-IP");
		String XFor = request.getHeader("X-Forwarded-For");
		if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
//多次反向代理后会有多个ip值，第一个ip才是真实ip
			int index = XFor.indexOf(",");
			if (index != -1) {
				return XFor.substring(0, index);
			} else {
				return XFor;
			}
		}
		XFor = Xip;
		if (StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)) {
			return XFor;
		}
		if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
			XFor = request.getHeader("Proxy-Client-IP");
		}
		if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
			XFor = request.getHeader("WL-Proxy-client-IP");
		}
		if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
			XFor = request.getHeader("HTTP_CLIENT_IP");
		}
		if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
			XFor = request.getHeader("HTTP_X_FORWARDED_FOR");
		}
		if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) {
			XFor = request.getRemoteAddr();
		}
		return XFor;
	}

}